package com.hmall.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.feign.client.ItemClient;
import com.hmall.feign.client.UserClient;
import com.hmall.feign.dto.Address;
import com.hmall.feign.pojo.Item;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.pojo.Order;
import com.hmall.order.pojo.OrderDetail;
import com.hmall.order.pojo.OrderLogistics;
import com.hmall.order.pojo.RequestParams;
import com.hmall.order.service.DetailService;
import com.hmall.order.service.LogisticsService;
import com.hmall.order.service.OrderService;
import com.hmall.order.util.ThreadLocalUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private ItemClient itemClient;

    @Autowired
    private UserClient userClient;

    @Autowired
    private DetailService detailService;

    @Autowired
    private LogisticsService logisticsService;

    // 创建订单业务
    @Override
    @Transactional
    public Long createOrder(RequestParams params) {
        /**
         * 需求:
         *  - 1）根据雪花算法生成订单id**(mybatisplus自带)**
         *         - 2）商品微服务提供FeignClient，实现根据id查询商品的接口
         *         - 3）根据itemId查询商品信息
         *         - 4）基于商品价格、购买数量计算商品总价：totalFee
         *         - 5）封装Order对象，初始status为未支付
         *         - 6）将Order写入数据库tb_order表中
         *         - 7）将商品信息、orderId信息封装为OrderDetail对象，写入tb_order_detail表
         *         - 8）将user-service的根据id查询地址接口封装为FeignClient
         *         - 9）根据addressId查询user-service服务，获取地址信息
         *         - 10）将地址封装为OrderLogistics对象，写入tb_order_logistics表
         *         - 11）在item-service提供减库存接口，并编写FeignClient
         *         - 12）调用item-service的减库存接口
         */
        //获取 itemId 并查询商品信息
        Item itemById = itemClient.searchItemById(params.getItemId());

        //获取商品价格 ，并计算商品总价： totalFee
        Long totalFee = params.getNum() * itemById.getPrice();

        //封装Order对象
        Order order = new Order();
        order.setTotalFee(totalFee);
        order.setPaymentType(params.getPaymentType());
        order.setUserId(ThreadLocalUtil.getUserId());
        order.setStatus(1);
        //将Order写入数据库tb_order表中
        this.save(order);

        //将商品信息、orderId信息封装为OrderDetail对象，写入tb_order_detail表
        OrderDetail detail = new OrderDetail();
        detail.setName(itemById.getName());
        detail.setSpec(itemById.getSpec());
        detail.setPrice(itemById.getPrice());
        detail.setNum(params.getNum());
        detail.setItemId(itemById.getId());
        detail.setImage(itemById.getImage());
        detail.setOrderId(order.getId());
        detailService.save(detail);

        //将user-service的根据id查询地址接口封装为FeignClient
        Long addressId = params.getAddressId();
        //根据addressId查询user-service服务，获取地址信息
        Address address = userClient.getAddr(addressId);

        //将地址封装为OrderLogistics对象，写入tb_order_logistics表
        OrderLogistics orderLogistics = new OrderLogistics();
        BeanUtils.copyProperties(address, orderLogistics);
        orderLogistics.setOrderId(order.getId());
        logisticsService.save(orderLogistics);

        try {
            //在item-service提供减库存接口，并编写FeignClient    调用item-service的减库存接口
            itemClient.updateStock(params.getItemId(), params.getNum());
        } catch (Exception e) {
            throw new RuntimeException("库存不足！");
        }
        return order.getId();
    }
}
